home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
More Source
/
Libraries
/
SpriteEngine
/
SE Balls
/
SpriteHanders.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-11
|
4KB
|
149 lines
#include "SpriteTools.h"
// SpriteTools.h includes SpriteHandlers.h
/*** Custom handlers - application dependent ***
Edit this as necessary. It should always include the following three routines:
MoveSprite: move the sprite
HitSprite: handle collisions between two sprites
InitSprites: Load all faces and create initial sprites
***/
GrafPtr firstFace, secondFace, thirdFace;
/* SeparateBalls is explicitly written to separate two balls with
diameter 32. */
#define kBallDiameterSquared (33*33)
static void SeparateBalls(SpritePtr theSprite, SpritePtr anotherSprite)
{
Point initVector, nowVector;
short absH, absV;
short moveH, moveV;
short frac;
/*Separate*/
frac = 0;
initVector.h = theSprite->position.h - anotherSprite->position.h;
initVector.v = theSprite->position.v - anotherSprite->position.v;
absH = abs(initVector.h);
absV = abs(initVector.v);
moveH = Sgn(initVector.h);
moveV = Sgn(initVector.v);
if ( moveH == 0 )
if ( moveV == 0 )
moveV = 1;
do
{
if ( absH > absV )
{
theSprite->position.h = theSprite->position.h + moveH;
anotherSprite->position.h = anotherSprite->position.h - moveH;
frac = frac + absV;
if ( frac > absH )
{
theSprite->position.v = theSprite->position.v + moveV;
anotherSprite->position.v = anotherSprite->position.v - moveV;
frac = frac - absH;
}
}
else
{
theSprite->position.v = theSprite->position.v + moveV;
anotherSprite->position.v = anotherSprite->position.v - moveV;
frac = frac + absH;
if ( frac > absV )
{
theSprite->position.h = theSprite->position.h + moveH;
anotherSprite->position.h = anotherSprite->position.h - moveH;
frac = frac - absV;
}
}
nowVector.h = theSprite->position.h - anotherSprite->position.h;
nowVector.v = theSprite->position.v - anotherSprite->position.v;
} while (! (long)nowVector.h * nowVector.h + (long)nowVector.v * nowVector.v > kBallDiameterSquared);
} /*SeparateBalls*/
void MoveSprite(SpritePtr theSprite)
{
theSprite->speed.v++; // Simple gravity
theSprite->fixedPointPosition.h += theSprite->speed.h;
theSprite->fixedPointPosition.v += theSprite->speed.v;
theSprite->position.h = theSprite->fixedPointPosition.h >> 4;
theSprite->position.v = theSprite->fixedPointPosition.v >> 4;
KeepOnScreenFixed(theSprite);
} /*MoveSprite*/
void HitSprite(SpritePtr theSprite, SpritePtr anotherSprite)
{
Point perpendicularHelpLine, parallelHelpLine, p1, p2, n1, n2;
//Check for a *real* collision!
if (RegionHit(theSprite, anotherSprite))
{
perpendicularHelpLine.h = theSprite->position.h - anotherSprite->position.h;
perpendicularHelpLine.v = theSprite->position.v - anotherSprite->position.v;
parallelHelpLine.h = perpendicularHelpLine.v;
parallelHelpLine.v = -perpendicularHelpLine.h;
//Move them away from each other}
SeparateBalls(theSprite, anotherSprite);
//Make the fixed-point positions follow!
theSprite->fixedPointPosition.h = theSprite->position.h << 4;
theSprite->fixedPointPosition.v = theSprite->position.v << 4;
anotherSprite->fixedPointPosition.h = anotherSprite->position.h << 4;
anotherSprite->fixedPointPosition.v = anotherSprite->position.v << 4;
//Swap the speed components that are parallell to parallelHelpLine
SplitVector(theSprite->speed, parallelHelpLine, &p1, &n1);
SplitVector(anotherSprite->speed, parallelHelpLine, &p2, &n2);
anotherSprite->speed.h = p2.h + n1.h;
anotherSprite->speed.v = p2.v + n1.v;
theSprite->speed.h = p1.h + n2.h;
theSprite->speed.v = p1.v + n2.v;
} // if RegionHit
} /*HitSprite*/
void InitSprites()
{
SpritePtr theSprite;
/*Load all pictures*/
firstFace = LoadFaceFromCicn(128); /*cicn resource #128.*/
secondFace = LoadFaceFromCicn(129); /*cicn resource #129.*/
thirdFace = LoadFaceFromCicn(130); /*cicn resource #130.*/
/*Create sprites*/
theSprite = NewSprite();
theSprite->face = firstFace;
SetPt(&theSprite->fixedPointPosition, 100 << 4, 100 << 4);
SetPt(&theSprite->speed, 1, 16);
theSprite = NewSprite();
theSprite->face = secondFace;
SetPt(&theSprite->fixedPointPosition, 50 << 4, 50 << 4);
SetPt(&theSprite->speed, 16, 1);
theSprite = NewSprite();
theSprite->face = thirdFace;
SetPt(&theSprite->fixedPointPosition, 150 << 4, 150 << 4);
SetPt(&theSprite->speed, Rand(7)-3, Rand(7)-3);
} /*InitSprites*/